package com.inews.business.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.inews.base.exception.BusinessException;
import com.inews.base.mapper.BeanMapper;
import com.inews.base.persistence.DynamicSpecifications;
import com.inews.base.persistence.SearchFilter;
import com.inews.base.persistence.SearchFilter.Operator;
import com.inews.base.security.vo.BaseUserVo;
import com.inews.base.utils.ExtDataUtil;
import com.inews.base.utils.InewsUtils;
import com.inews.base.vo.ExtData;
import com.inews.business.constants.InewsBusinessConstants;
import com.inews.business.entity.TblSysRole;
import com.inews.business.entity.TblSysUser;
import com.inews.business.entity.TblSysUserRole;
import com.inews.business.repository.SysRoleDao;
import com.inews.business.repository.SysUserDao;
import com.inews.business.repository.SysUserRoleDao;
import com.inews.business.vo.SysRoleVo;
import com.inews.business.vo.SysUserVo;

@Service
public class SysUserServiceImpl implements SysUserService, InewsBusinessConstants{
	
	@Autowired
	private SysUserDao userDao;
	@Autowired
	private SysUserRoleDao userRoleDao;
	@Autowired
	private SysRoleDao roleDao;
	@Autowired
	private PasswordEncoder passwordEncoder; 
	@Autowired
	private BaseService baseService;
	
	
	
	/**
	 * 分页查询系统用户.
	 *
	 * @param filterParams the filter params
	 * @param page the page
	 * @return the ext data
	 */
	@Transactional(readOnly=true)
	public ExtData<SysUserVo> findSysUserPage(Map<String, Object> filterParams, Pageable page){
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		//查询正常状态用户
		filters.put("status", new SearchFilter("status", Operator.EQ, USER_STATUS_NORMAL));
		Page<TblSysUser> pagePoList = userDao.findAll(DynamicSpecifications.bySearchFilter(filters.values(), TblSysUser.class), page);
		ExtData<SysUserVo> extData = ExtDataUtil.genWithPagingList(pagePoList, SysUserVo.class);
		return extData;
	}

	
	/**
	 * 新增系统用户信息.
	 *
	 * @param vo the vo
	 * @param user the user
	 * @return the ext data
	 */
	@Transactional(readOnly=false)
	public ExtData<SysUserVo> saveSysUser(SysUserVo vo, BaseUserVo user){
		String currentTime = baseService.getCurrentTime();
		TblSysUser editUser = baseService.getEditUser(user);
		//对提交的用户信息进行校验
		this.validateSysUser(vo);
		TblSysUser po = BeanMapper.map(vo, TblSysUser.class);
		po.setPassword(passwordEncoder.encode(vo.getPassword()));
		po.setStatus(USER_STATUS_NORMAL);
		po.setCreateTime(currentTime);
		po.setCreateUser(editUser);
		po.setLastUpdUser(editUser);
		po.setLastUpdDes(LAST_UPD_DES_ADD);
		po.setLastUpdTime(currentTime);
		userDao.save(po);
		return ExtDataUtil.genWithSingleData(vo);
	}


	
	
	/**
	 * 更新系统用户.
	 *
	 * @param vo the vo
	 * @param user the user
	 * @return the ext data
	 * @throws Exception the exception
	 */
	@Transactional(readOnly=false)
	public ExtData<SysUserVo> updateSysUser(SysUserVo vo, BaseUserVo user){
		String currentTime = baseService.getCurrentTime();
		TblSysUser editUser = baseService.getEditUser(user);
		TblSysUser po = userDao.findOne(vo.getUserId());
		po.setRealName(vo.getRealName());
		po.setEmail(vo.getEmail());
		po.setMobile(vo.getMobile());
		po.setLastUpdUser(editUser);
		po.setLastUpdDes(LAST_UPD_DES_UPDATE);
		po.setLastUpdTime(currentTime);
		userDao.save(po);
		return ExtDataUtil.genWithSingleData(vo);
	}
	
	
	
	/**
	 * 删除系统用户.
	 *
	 * @param vo the vo
	 * @param user the user
	 * @return the ext data
	 */
	@Transactional(readOnly=false)
	public ExtData<SysUserVo> deleteSysUser(SysUserVo vo, BaseUserVo user){
		String currentTime = baseService.getCurrentTime();
		TblSysUser editUser = baseService.getEditUser(user);
		TblSysUser po = userDao.findOne(vo.getUserId());
		po.setStatus(USER_STATUS_DELETE);
		po.setLastUpdUser(editUser);
		po.setLastUpdDes(LAST_UPD_DES_DELETE);
		po.setLastUpdTime(currentTime);
		userDao.save(po);
		return ExtDataUtil.genWithSingleData(vo);
	}
	
	
	
	/**
	 * 根据用户Id查询对应的角色信息.
	 *
	 * @param userId the user id
	 * @throws Exception the exception
	 */
	@Transactional(readOnly=true)
	public ExtData<SysRoleVo> findRoleByUser(SysUserVo vo){
		List<SysRoleVo> voList = new ArrayList<SysRoleVo>();
		Long userId = vo.getUserId();
		TblSysUser userPo = userDao.findOne(userId);
		Set<TblSysUserRole> userRoles = userPo.getUserRoles();
		for (TblSysUserRole userRole : userRoles) {
			TblSysRole rolePo = userRole.getRole();
			SysRoleVo roleVo = BeanMapper.map(rolePo, SysRoleVo.class);
			voList.add(roleVo);
		}
		return ExtDataUtil.genWithData(voList);
	}
	
	
	
	/**
	 * 分配用户角色.
	 *
	 * @param vo the vo
	 * @param roleVoList the role vo list
	 * @param user the user
	 * @return the ext data
	 */
	@Transactional(readOnly=false)
	public ExtData<SysUserVo> chooseRole(SysUserVo vo, List<SysRoleVo> roleVoList, BaseUserVo user){
		String currentTime = baseService.getCurrentTime();
		TblSysUser editUser = baseService.getEditUser(user);
		Long userId = vo.getUserId();
		TblSysUser userPo = userDao.findOne(userId);
		//删除原有的用户角色对应关系
		Set<TblSysUserRole> userRoles = userPo.getUserRoles();
		userRoleDao.delete(userRoles);
		//添加用户角色信息
		for (SysRoleVo sysRoleVo : roleVoList) {
			TblSysRole rolePo = roleDao.findOne(sysRoleVo.getRoleId());
			TblSysUserRole userRolePo = new TblSysUserRole(userPo, rolePo);
			userRoleDao.save(userRolePo);
		}
		//更新最后修改用户和时间
		userPo.setLastUpdTime(currentTime);
		userPo.setLastUpdUser(editUser);
		userPo.setLastUpdDes(InewsBusinessConstants.LAST_UPD_DES_UPDATE);
		userDao.save(userPo);
		return ExtDataUtil.genWithSingleData(vo);
	}

	
	
	
	 /* 重置密码.
	 *
	 * @param vo the vo
	 * @param user the user
	 * @return the ext data
	 * @throws Exception the exception
	 */
	@Override
	public ExtData<SysUserVo> doResetPassword(SysUserVo vo, BaseUserVo user){
		validatePassword(vo);
		String currentTime = baseService.getCurrentTime();
		TblSysUser editUser = baseService.getEditUser(user);
		Long userId = vo.getUserId();
		//Map<String, SearchFilter> filters = new HashMap<String,SearchFilter>();
		//查询正常状态用户
		//filters.put("status", new SearchFilter("userId", Operator.EQ, userId));
//		List<Filter> filters = new ArrayList<Filter>();
//		filters.add(new Filter("userId", Filter.STRING, userId, Comparison.EQ));
		//List<TblBaseUser> userPoList = userDao.findSysUserPo(filters);
		TblSysUser tuser=  userDao.findOne(userId);
//		if(InewsUtils.isNotEmpty(userPoList)){
//			TblBaseUser po = userPoList.get(0);
//			po.setPassword(passwordEncoder.encode(vo.getPassword()));
//			po.setLastUpdTime(currentTime);
//			po.setLastUpdUserId(user.getUserId());
//			po.setLastUpdDes("重置密码");
//			userDao.doUpdateBaseUserPo(po);
//		}
		if(tuser!=null){
			tuser.setPassword(passwordEncoder.encode(vo.getPassword()));
			tuser.setLastUpdTime(currentTime);
			tuser.setLastUpdUser(editUser);
			tuser.setLastUpdDes("重置密码");
			userDao.save(tuser);
		}
		return ExtDataUtil.genWithSingleData(vo);
	}
//	
	
	
	
	/**
	 * 对用户信息进行校验.
	 *
	 * @param vo the vo
	 * @throws Exception 
	 */
	private void validateSysUser(final SysUserVo vo) {
		List<TblSysUser> users = userDao.findByUserName(vo.getUserName());
		if(!users.isEmpty()){
			throw new BusinessException("该用户名已经存在");
		}
		validatePassword(vo);
	}
	
	
	/**
	 * 校验密码是否重复.
	 *
	 * @param vo the vo
	 * @throws Exception the exception
	 */
	private void validatePassword(final SysUserVo vo){
		String password = vo.getPassword();
		String againPassword = vo.getAgainPassword();
		if(!password.equals(againPassword)){
			throw new BusinessException("两次输入的密码不一致，请重新输入");
		}
	}
	
	
}
